package builder;

import java.util.ArrayList;
import java.util.Map;

import controller.Controller;
import model.*;

/**
 * 
 * This class builds a CSV file. 
 * @author Roman Pusec, Dennis Goldfinger, Marko Bilic
 *
 */
public class CSVBuilder extends FileBuilder {

	@Override
	public String buildFile(ArrayList<DailyLog> dailyLogs, Controller controller) {
		 String csvString = "";
		 String newLine = "\n";
		 
		 for(DailyLog log : dailyLogs)
		 {			 
			 // Getting date elements
			 String[] dateArr = (log.getDate()).split("\\.");
			 String year = dateArr[2];
			 String month = dateArr[1];
			 String day = dateArr[0];
			 
			 // Adding the date elements to the csv string
			 csvString += "date," + year + "," + month + "," + day + "," + 
					 log.getLimit() + "," + log.getWeight() + newLine;			 
			 
			 // Handle consumed items
			 Map<Food, Integer> intake = log.getIntake();
			 csvString += buildConsumed(intake, controller);
			 
			 // Handle expended items
			 Map<Activity, Integer> activities = log.getActivities();
			 csvString += buildExpended(activities, controller);
		 }
		 
		 return csvString;
	}
	
	/**
	 * Builds the consumed food. 
	 * @param intake Intake of foods/recipes.
	 * @param controller The controller. 
	 * @return List of consumed food. 
	 */
	private String buildConsumed(Map<Food, Integer> intake, Controller controller)
	{
		String newLine = "\n";
		String consumed = "";

		// Loop through intake
		for (Map.Entry<Food, Integer> entry : intake.entrySet()) 
		{
			Food food = controller.getFoodByFood(entry.getKey());

			// For each basic food, make an entry (accounts for quantity)
			if (food instanceof Basic) 
			{
				Basic basic = (Basic) food;

				double calories = basic.getCalories() * entry.getValue();

				consumed += "food," + basic.getName() + ",";
				consumed += calories + ",";
				consumed += basic.getFat() * .01 * calories + ",";
				consumed += basic.getCarbs() * .01 * calories + ",";
				consumed += basic.getProtein() * .01 * calories + newLine;
			}
			// For each recipe, make an entry which accounts for all basic foods
			// in the ingredients
			else if (food instanceof Recipe) 
			{
				Recipe recipe = (Recipe) food;

				Map<Food, Integer> ingredients = recipe.getFoods();

				String name = recipe.getName();
				double calories = 0;
				double fat = 0;
				double carbs = 0;
				double protein = 0;

				// Loop through ingredients to get total counts (accounts for
				// quantity)
				// Note: recursion needs to be implemented here for accuracy, too lazy though
				for (Map.Entry<Food, Integer> item : ingredients.entrySet()) 
				{
					Food ingredient = controller.getFoodByFood(item.getKey());
					
					if(ingredient instanceof Basic)
					{
						Basic basic = (Basic) ingredient;

						calories += basic.getCalories() * item.getValue();
						fat += basic.getFat() * .01 * calories;
						carbs = basic.getCarbs() * .01 * calories;
						protein = basic.getProtein() * .01 * calories;
					}
				}

				consumed += "food," + name + ",";
				consumed += calories + ",";
				consumed += fat + ",";
				consumed += carbs + ",";
				consumed += protein + newLine;
			}
		}
		
		return consumed;
	}
	
	/**
	 * Builds the list of expended calories. 
	 * @param activities List of activities. 
	 * @param controller The controller. 
	 * @return List of expended calories. 
	 */
	private String buildExpended(Map<Activity, Integer> activities, Controller controller)
	{
		String newLine = "\n";
		String expended = "";

		// Loop through intake
		for (Map.Entry<Activity, Integer> entry : activities.entrySet()) 
		{
			Activity activity = controller.getActivityByActivity(entry.getKey());

			// For each exercise, make an entry
			if (activity instanceof Exercise) 
			{
				Exercise exercise = (Exercise) activity;

				double calories = exercise.getExpenditure() * entry.getValue();

				expended += "exercise," + exercise.getName() + ",";
				expended += calories + newLine;
			}
			// For each workout, make an entry which accounts for all sub activities
			else if (activity instanceof Workout) 
			{
				Workout workout = (Workout) activity;

				Map<Activity, Integer> activities_2 = workout.getActivities();

				String name = workout.getName();
				double calories = 0;

				// Loop through sub activities to get total counts (accounts for
				// quantity)
				// Note: recursion needs to be implemented here for accuracy, too lazy though
				for (Map.Entry<Activity, Integer> item : activities_2.entrySet()) 
				{
					Activity sub_activity = controller.getActivityByActivity(item.getKey());
					
					if(sub_activity instanceof Exercise)
					{
						Exercise exercise = (Exercise) sub_activity;

						calories += exercise.getExpenditure() * item.getValue();
					}
				}

				expended += "exercise," + name + ",";
				expended += calories + newLine;
			}
		}
		
		return expended;
	}
}
